/**
 * 配置适配器模块
 * 
 * 该模块用于处理不同环境下的配置加载和适配
 * 支持从环境变量、配置文件等多种方式获取配置
 * 
 * @module configAdapter
 */

import fs from 'fs';
import path from 'path';
import os from 'os';
import { fileURLToPath } from 'url';

// 获取当前文件目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

/**
 * 默认配置
 * @type {Object}
 */
const DEFAULT_CONFIG = {
    AUTO_API_BASE_URL: 'http://localhost:3000',
    PROJECT_ID: 'default',
    SCHEMA_NAME: 'public',
    OUTPUT_BASE_DIR: '../',
    RAW_DATA_DIR: 'raw-data',
    CONFIG_DIR: 'config',
    LOGS_DIR: 'logs',
    TYPES_DIR: 'types',
    TABLES_DIR: 'tables',
    ENABLE_CACHE: 'true',
    TOKEN_CACHE_EXPIRE: '604800000',
    DOC_FORMAT: 'markdown',
    INCLUDE_API_EXAMPLES: 'true'
};

/**
 * 加载配置文件
 * 
 * @param {string} configPath - 配置文件路径
 * @returns {Object} 配置对象
 */
function loadConfigFile(configPath) {
    if (!fs.existsSync(configPath)) {
        console.warn(`配置文件不存在: ${configPath}`);
        return {};
    }

    try {
        console.log('正在加载配置文件...');
        const config = {};
        const content = fs.readFileSync(configPath, 'utf8');

        // 解析配置文件中的键值对
        content.split('\n').forEach(line => {
            // 跳过注释和空行
            if (line.trim().startsWith('#') || !line.trim()) return;

            // 提取键值对
            const match = line.match(/^([A-Z0-9_]+)="([^"]*)"/);
            if (match) {
                const [, key, value] = match;
                config[key] = value;

                // 处理特殊情况，如引用其他变量
                if (value.includes('${')) {
                    const refMatch = value.match(/\${([^}]*)}/);
                    if (refMatch && config[refMatch[1]]) {
                        config[key] = value.replace(/\${[^}]*}/, config[refMatch[1]]);
                    }
                }
            }
        });

        console.log('配置文件加载成功');
        return config;
    } catch (error) {
        console.error('加载配置文件失败:', error);
        return {};
    }
}

/**
 * 从环境变量加载配置
 * 
 * @returns {Object} 环境变量中的配置
 */
function loadEnvConfig() {
    const envConfig = {};

    // 获取相关环境变量
    Object.keys(DEFAULT_CONFIG).forEach(key => {
        if (process.env[key]) {
            envConfig[key] = process.env[key];
        }
    });

    return envConfig;
}

/**
 * 合并多个配置对象
 * 
 * @param {...Object} configs - 多个配置对象
 * @returns {Object} 合并后的配置
 */
function mergeConfigs(...configs) {
    return Object.assign({}, ...configs);
}

/**
 * 验证配置的有效性
 * 
 * @param {Object} config - 配置对象
 * @returns {Object} 带有验证信息的配置对象
 */
function validateConfig(config) {
    const validatedConfig = { ...config };
    const errors = [];
    const warnings = [];

    // 必填字段检查
    const requiredFields = ['AUTO_API_BASE_URL', 'PROJECT_ID'];
    requiredFields.forEach(field => {
        if (!validatedConfig[field]) {
            errors.push(`缺少必要配置项: ${field}`);
        }
    });

    // URL格式检查
    if (validatedConfig.AUTO_API_BASE_URL) {
        try {
            new URL(validatedConfig.AUTO_API_BASE_URL);
        } catch (e) {
            warnings.push(`API基础URL格式可能不正确: ${validatedConfig.AUTO_API_BASE_URL}`);
        }
    }

    // 路径检查和修正
    ['OUTPUT_BASE_DIR', 'RAW_DATA_DIR', 'CONFIG_DIR', 'LOGS_DIR', 'TYPES_DIR', 'TABLES_DIR'].forEach(dir => {
        if (validatedConfig[dir]) {
            // 替换路径中的环境变量
            validatedConfig[dir] = validatedConfig[dir].replace(/\$\{([^}]+)\}/g, (match, envVar) => {
                return process.env[envVar] || os.homedir();
            });

            // 转换相对路径为绝对路径
            if (!path.isAbsolute(validatedConfig[dir])) {
                validatedConfig[dir] = path.resolve(process.cwd(), validatedConfig[dir]);
            }
        }
    });

    return {
        config: validatedConfig,
        valid: errors.length === 0,
        errors,
        warnings
    };
}

/**
 * 根据平台调整配置
 * 
 * @param {Object} config - 配置对象
 * @returns {Object} 平台适配后的配置
 */
function adaptConfigForPlatform(config) {
    const platform = os.platform();
    const adaptedConfig = { ...config };

    // Windows平台适配
    if (platform === 'win32') {
        // 确保路径分隔符正确
        Object.keys(adaptedConfig).forEach(key => {
            if (typeof adaptedConfig[key] === 'string' && adaptedConfig[key].includes('/')) {
                adaptedConfig[key] = adaptedConfig[key].replace(/\//g, '\\');
            }
        });
    }

    return adaptedConfig;
}

/**
 * 获取完整配置
 * 
 * @param {string} [configPath] - 配置文件路径，默认为脚本目录下的env.config
 * @returns {Object} 完整的配置对象
 */
function getConfig(configPath) {
    // 默认配置文件路径
    const defaultConfigPath = path.join(__dirname, 'env.config');
    const finalConfigPath = configPath || defaultConfigPath;

    // 加载并合并配置
    const fileConfig = loadConfigFile(finalConfigPath);
    const envConfig = loadEnvConfig();
    const mergedConfig = mergeConfigs(DEFAULT_CONFIG, fileConfig, envConfig);

    // 验证配置
    const { config, valid, errors, warnings } = validateConfig(mergedConfig);

    // 输出错误和警告
    if (errors.length > 0) {
        console.error('配置错误:');
        errors.forEach(err => console.error(`- ${err}`));
    }

    if (warnings.length > 0) {
        console.warn('配置警告:');
        warnings.forEach(warn => console.warn(`- ${warn}`));
    }

    // 平台适配
    const adaptedConfig = adaptConfigForPlatform(config);

    return adaptedConfig;
}

export {
    getConfig,
    loadConfigFile,
    validateConfig
}; 